﻿using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using ID3Tag;
using ID3Tag.HighLevel;
using ID3Tag.HighLevel.ID3Frame;
using ID3Tag.LowLevel;

namespace ZenWplExporter
{
	/// <summary>
	/// Reads ID Tags
	/// </summary>
	internal class Id3TagReader
	{
		//  Create the controllers from the factory.
		private readonly IIoController _ioController = Id3TagFactory.CreateIoController();
		private readonly IId3V1Controller _tag1Controller = Id3TagFactory.CreateId3V1Controller();
		private readonly ITagController _tag2Controller = Id3TagFactory.CreateTagController();

		/// <summary>
		/// Gets the music info.
		/// </summary>
		/// <param name="path">The path.</param>
		/// <returns></returns>
		[SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily",
			Justification = "Cast is in the loop and it is required.")]
		public MusicFileInfo ReadMusicInfo(string path)
		{
			var info = new MusicFileInfo();

			var file = new FileInfo(path);
			FileState state = _ioController.DetermineTagStatus(file);

			if (state.Id3V2TagFound)
			{
				//  Read the tag
				Id3TagInfo tagInfo = _ioController.Read(file);
				TagContainer container = _tag2Controller.Decode(tagInfo, 1251);

				string artist = null;

				foreach (IFrame frame in container)
				{
					if (frame is TextFrame)
					{
						var textFrame = (TextFrame)frame;
						switch (textFrame.Descriptor.ID)
						{
							case "TPE1": // Contributing Artist
								artist = textFrame.Content;
								break;
							case "TPE2": // Album Artist
								info.Artist = textFrame.Content;
								break;
							case "TALB":
								info.Album = textFrame.Content;
								break;
							case "TIT2":
								info.Title = textFrame.Content;
								break;
						}
					}
				}

				if (String.IsNullOrEmpty(info.Artist))
				{
					info.Artist = artist;
				}
			}
			else if (state.Id3V1TagFound)
			{
				Id3V1Tag tag = _tag1Controller.Read(file);
				info.Artist = tag.Artist;
				info.Album = tag.Album;
				info.Title = tag.Title;
			}
			else
			{
				throw new InvalidOperationException(String.Format("File [{0}] does not include ID3 tag.", file));
			}

			return info;
		}
	}
}